﻿using ModbusDataParseTool.Utility;
using MyUtility.Utility;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ModbusDataParseTool.Service
{
    public class LogService
    {
        public ConcurrentQueue<string> LogQueue = new ConcurrentQueue<string>();

        public bool IsRun { get; set; }

        public Thread WriteLogThread = null;

        #region 接收事件委托
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void RecvLogEventHandler(string LogStr);//接收事件委托
        //添加委托
        public static RecvLogEventHandler OnRecvLogEvent;

        public static event RecvLogEventHandler RecvLog
        {
            add { OnRecvLogEvent += new RecvLogEventHandler(value); }
            remove { OnRecvLogEvent -= new RecvLogEventHandler(value); }
        }

        #endregion

        public LogService()
        {
            IsRun = true;
            WriteLogThread = new Thread(WriteLog);
            WriteLogThread.IsBackground = true;
            WriteLogThread.Start();
        }


        public void WriteLog()
        {
            StringBuilder stringBuilder = new StringBuilder();
            long lastWriteTime = UnixTime.GetTimeStampTen();
            long nowWriteTime = 0;
            while (IsRun)
            {
                try
                {
                    if (LogQueue.Count > 0)
                    {
                        bool isGet = LogQueue.TryDequeue(out string str);
                        if (isGet && !string.IsNullOrEmpty(str))
                        {
                            stringBuilder.AppendLine(str);
                        }
                    }
                    nowWriteTime = UnixTime.GetTimeStampTen() - lastWriteTime;
                    //stringBuilder大于4k或距离上次时间大于5分钟，则进行记录
                    if (stringBuilder.Length > 4096 || nowWriteTime > 300)
                    {
                        LogHelper.WriteLog(stringBuilder.ToString());
                        stringBuilder.Clear();
                        lastWriteTime = UnixTime.GetTimeStampTen();
                    }
                    Thread.Sleep(5);
                }
                catch(Exception ex)
                {
                    IsRun = false;
                    LogHelper.WriteLog("WriteLog", ex);
                }
            }
        }

        public void AddLog(string strLog)
        {
            if (string.IsNullOrEmpty(strLog))
            {
                return;
            }
            string strLogAddTime = DateTime.Now + ":" + strLog;
            OnRecvLogEvent(strLogAddTime);
            LogQueue.Enqueue(strLogAddTime);
        }

    }
}
